package com.wl.util;

import com.mysql.cj.util.StringUtils;
import com.wl.constant.Constant;
import com.wl.pojo.model.UserToken;
import lombok.SneakyThrows;
import org.jose4j.jws.AlgorithmIdentifiers;
import org.jose4j.jws.JsonWebSignature;
import org.jose4j.jwt.JwtClaims;
import org.jose4j.jwt.consumer.JwtConsumer;
import org.jose4j.jwt.consumer.JwtConsumerBuilder;
import org.jose4j.keys.HmacKey;
import org.jose4j.lang.JoseException;
import redis.clients.jedis.Jedis;

import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.security.Key;

/**
 * Token工具类
 *
 * @program: treeHole
 * @author: 吴磊
 * @create: 2021-07-06 20:16
 */
public class TokenUtils {

    /**
     * 生成Token
     *
     * @param userToken
     * @return
     * @throws Exception
     */
    public static String generateToken(UserToken userToken) throws UnsupportedEncodingException, JoseException {
        JwtClaims claims = new JwtClaims();
        claims.setSubject(userToken.getUserId());
        claims.setClaim(Constant.CONTEXT_NAME, userToken.getUserName());
        claims.setClaim(Constant.CONTEXT_PHONE, userToken.getUserTelephoneNumber());
        claims.setClaim(Constant.CONTEXT_IMAGE, userToken.getUserProfilePhoto());
        claims.setClaim(Constant.CONTEXT_DATE, userToken.getUserRegistrationTime());
        //设置token的过期时间为1天，redis中也是一天
        claims.setExpirationTimeMinutesInTheFuture(60 * 24);
        Key key = new HmacKey(Constant.JWT_PRIVATE_KEY.getBytes("UTF-8"));
        JsonWebSignature jws = new JsonWebSignature();
        jws.setPayload(claims.toJson());
        jws.setAlgorithmHeaderValue(AlgorithmIdentifiers.HMAC_SHA256);
        jws.setKey(key);
        jws.setDoKeyValidation(false); // relaxes the key length requirement
        //签名
        String token = jws.getCompactSerialization();
        return token;
    }

    /**
     * 从Token中获取信息(解析token成UserToken对象)
     *
     * @param token
     * @return
     * @throws Exception
     */

    @SneakyThrows
    public static UserToken parseTokenToUserToken(String token) {
        Jedis jedis = RedisUtil.getJedis();
        if (StringUtils.isNullOrEmpty(token) || !jedis.exists(token)) {
            jedis.close();
            return null;
        }
        Key key = new HmacKey(Constant.JWT_PRIVATE_KEY.getBytes("UTF-8"));
        JwtConsumer jwtConsumer = new JwtConsumerBuilder()
                .setRequireExpirationTime()
                .setAllowedClockSkewInSeconds(30)
                .setRequireSubject()
                .setVerificationKey(key)
                .setRelaxVerificationKeyValidation() // relaxes key length requirement
                .build();
        JwtClaims processedClaims = jwtConsumer.processToClaims(token);
        return new UserToken(
                processedClaims.getSubject(),
                processedClaims.getClaimValue(Constant.CONTEXT_NAME).toString(),
                processedClaims.getClaimValue(Constant.CONTEXT_PHONE).toString(),
                processedClaims.getClaimValue(Constant.CONTEXT_IMAGE).toString(),
                processedClaims.getClaimValue(Constant.CONTEXT_DATE).toString());
    }

    /**
     * 单单判断是否登录
     *
     * @return
     */
    public static String parseTokenToken(HttpServletRequest request) {
        String token = request.getHeader("Authorization");
        Jedis jedis = RedisUtil.getJedis();
        if (StringUtils.isNullOrEmpty(token) || "null".equals(token) || !jedis.exists(token)) {
            jedis.close();
            return "";
        }
        jedis.close();
        return token;
    }

    /**
     * 获取当前登录的用户，没登录返回null
     *
     * @param request
     * @return
     */
    public static UserToken getUser(HttpServletRequest request) {
        String token = parseTokenToken(request);
        UserToken userToken = parseTokenToUserToken(token);
        return userToken;
    }


}
